home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_200
/
235_01
/
ovdir.c
< prev
next >
Wrap
Text File
|
1987-06-16
|
25KB
|
735 lines
/* 030 14-Feb-87 ovdir.c
Copyright (c) 1987 by Blue Sky Software. All rights reserved.
*/
#include <stdio.h>
#include "ov.h"
#include "dosfile.h"
#define DCOLSIZ 15
#define DCOLS (SCREEN_COLS / DCOLSIZ)
#define dr2sr(r) (FIRST_NROW + (r - drbase))
#define dc2sc(c) ((c - dcbase) * DCOLSIZ)
#define TO_NONE 0
#define TO_SUBDIR 1
#define TO_SIBLING 2
#define TO_PARENT 3
#define TO_ROOT 4
char *strrchr(), *strupr();
struct search_block *nxtfile();
struct dir_ent {
struct dir_ent *subdir;
struct dir_ent *sibling;
struct dir_ent *parent;
struct dir_ent *prev_sib;
char name[13];
unsigned char row;
unsigned char col;
};
static last_drive = ' ';
static int drow, dcol, ldrow;
static char dirpath[MAX_PATHLEN+6];
static int drbase, drend, dcbase, dcend;
static struct dir_ent *curdir, *logdir, *findir();
static struct dir_ent root = { NULL, NULL, NULL, NULL, "", 0, 0 };
int dir_exit(), dir_login(), dir_mkdir(), dir_rmdir(), dir_new();
extern struct menu_selection top_file_menu[], *top_menu;
struct menu_selection top_dir_menu[] = {
{ "Login", "Login (switch) to the highlighted directory", dir_login, NULL },
{ "Mkdir", "Make a subdirectory of the highlighted directory", dir_mkdir, NULL },
{ "New", "Reread and redisplay directory tree", dir_new, NULL },
{ "Rmdir", "Remove (delete) the highlighted directory", dir_rmdir, NULL },
{ "Quit", "Return to file display", dir_exit, top_file_menu },
{ NULL, NULL, NULL, NULL }
};
extern struct window cw;
extern unsigned char dir_display, restricted;
char *strchr();
/******************************************************************************
** D T R E E **
*****************************************************************************/
dtree() { /* display / work with directory tree */
int drive;
dir_display = TRUE; /* dir tree is (will be) displayed */
restricted = TRUE; /* disable some file commands */
/* scan the current disk and create the internal directory tree if it
hasn't already been built or the user has changed disks */
if ((drive = current_drive()) != last_drive) { /* has the drive switched? */
if (root.subdir) { /* delete current tree */
del_dtree(root.subdir); /* if drive switch */
root.subdir = NULL;
}
last_drive = drive;
*dirpath = '\0'; /* scan_dir() starts at */
strncat(dirpath,cw.dirbuf,3); /* drives root dir */
strcpy(root.name,dirpath);
disp_msg(1,"Scanning disk"); /* takes awhile, tell user */
scan_dir(&root); /* build new dir tree */
clr_msg(); /* done scanning */
drbase = dcbase = 0; /* assume dir */
drend = NAME_ROWS; /* will start */
dcend = DCOLS; /* at the root */
curdir = findir(); /* locate current dir in tree */
} else { /* don't need to scan the disk */
curdir = findir(); /* point to logged in dir */
adj_dir_dis(); /* make sure logged dir will show */
}
logdir = curdir; /* remember the logged dir */
/* now display the current portion of the dir tree */
show_tree(); /* let user see it */
/* this is a hack, but... if a new drive was scanned, we don't know for
sure if the curent dir is really displayed because the row/column
values aren't calculated until it's actully displayed. If the
user has more than a screen's worth of directories and he is in one
of the ones off screen, adjust the offsets and redisplay, sigh... */
if (adj_dir_dis())
show_tree();
top_menu = top_dir_menu; /* setup the dir menu as the main menu */
}
/******************************************************************************
D I R _ N E W
*****************************************************************************/
dir_new() { /* rescan the disk and redisplay the dir tree */
last_drive = ' '; /* simply force a rescan */
dtree(); /* and let dtree() do the work */
update_vol_stats(); /* in case its a new volume */
}
/******************************************************************************
** D I R _ E X I T **
*****************************************************************************/
dir_exit() { /* exit the dir display, return to file display */
dir_display = FALSE; /* dir tree will not be displayed */
restricted = FALSE; /* allow all file commands */
top_menu = top_file_menu; /* file menu is main again */
update_header(); /* always rewrite the entire screen */
refresh_screen(0); /* 'cause there may be > windows */
}
/******************************************************************************
** S C A N _ D I R **
*****************************************************************************/
scan_dir(dp) /* scan the specified dir tree for other directories */
struct dir_ent *dp;
{
int dplen;
int firsttime = TRUE;
struct search_block *sbp;
register struct dir_ent *ndp, *ldp = NULL;
/* build the pathname of the dir to scan */
dplen = strlen(dirpath); /* remember callers length */
if (strcmp(dp->name+2,"\\") != 0) { /* special case if root dir */
strcat(dirpath,dp->name); /* add name of dir to scan */
strcat(dirpath,"\\");
}
strcat(dirpath,"*.*"); /* add wildcard string */
/* scan all files in directory looking for subdirectories. When a
subdirectory is found, add it to the dir_ent tree. Note, the . and
.. directory entries are ignored. */
while (sbp = nxtfile(dirpath,0x16,&firsttime))
if (sbp->attrib & DIR && *sbp->fn != '.') {
/* found a subdir we want, build a struct dir_ent for it */
ndp = (struct dir_ent *) Malloc(sizeof(struct dir_ent));
strcpy(ndp->name,sbp->fn);
ndp->subdir = NULL;
ndp->sibling = NULL;
ndp->parent = dp;
ndp->prev_sib = ldp;
/* now link it to the dir_ent tree either as a subdir of the
parent (1st one only) or a sibling of the last one */
if (ldp)
ldp->sibling = ndp; /* not 1st, is a sibling */
else
dp->subdir = ndp; /* 1st one, subdir of parent */
ldp = ndp; /* new one is now the last one */
}
/* if any subdirectories were found, scan 'em. This isn't done
earlier so the file search isn't complicated by the directory
switches. */
if (ldp) { /* NULL if no sub's found */
dirpath[strlen(dirpath)-3] = '\0'; /* remove *.* for next level */
ldp = dp->subdir; /* start with the first one */
do {
scan_dir(ldp); /* call ourselves to scan this subtree */
} while (ldp = ldp->sibling); /* do all the subs found */
}
dirpath[dplen] = '\0'; /* restore dir pathname for caller */
}
/******************************************************************************
** D E L _ D T R E E **
*****************************************************************************/
del_dtree(dp) /* purge the current in memory dir tree structure */
register struct dir_ent *dp;
{
register struct dir_